package com.hrg.rds.infra.connect.protocol.s7;

import com.hrg.rds.infra.connect.ConnectionHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.PlcConnectionManager;
import org.apache.plc4x.java.utils.cache.CachedPlcConnectionManager;

import java.time.Duration;

// 支持 同步异步读写、同步异步订阅、轮询、连接池
// For example a S7-1200 typically allows 3 concurrent connections.
@Slf4j
public class S7ConnectionHolder implements ConnectionHolder {
	private final S7Properties s7Properties;

	private final PlcConnectionManager connectionManager;

	S7ConnectionHolder(S7Properties s7Properties) {
		// CachedPlcConnectionManager 可直接替换 PlcConnectionManager.
		// 通过方法创建 CachedPlcConnectionManager = CachedPlcConnectionManager.getBuilder()
		// 使用 try-with-resources statement (i.e. try (PlcConnection connection = connectionManager.getConnection(connectionString)))
		// connection 会被cache自动关闭，默认 maxLeaseTime = 4s，可配置
		// cache 会自动续约 connection-lease，执行 ping()方法，如果失败会终止connection，然后创建一个新的connection的句柄handle

		this.s7Properties = s7Properties;
		this.connectionManager = CachedPlcConnectionManager.getBuilder()
				//maxLeaseTime 默认4s,线程可以拥有该连接的最大时长，超过后线程不能再使用，会被cache终止租约
				.withMaxLeaseTime(Duration.ofMillis(s7Properties.getMaxLeaseTime()))
				// maxWaitTime 默认20s，线程申请的最大等待时长，超过后cache抛出异常PlcConnectionException
				.withMaxWaitTime(Duration.ofMillis(s7Properties.getMaxWaitTime()))
				.build();
	}

	@Override
	public PlcConnection getConnection(String connId) throws Exception {
		return getConnection(this.connectionManager, connId);
	}
}
